import re
import subprocess
import time
import os
from fastapi import FastAPI, APIRouter, HTTPException
from fastapi.responses import JSONResponse

class ADBManager:
    def __init__(self, device_id=None):
        self.device_id = device_id


    def run_adb_command(self, command):
        full_command = ["adb"]

        # 如果没有设置 device_id，自动选择第一个设备
        if (not self.device_id) and command[0] not in ["start-server", "kill-server"]:
            try:
                output = subprocess.check_output(["adb", "devices"]).decode().splitlines()
                devices = [line.split()[0] for line in output[1:] if line.strip() and "device" in line]
                if not devices:
                    raise RuntimeError("没有找到可用设备")
                self.device_id = devices[0]
                print(f"Auto-selected device: {self.device_id}")
            except Exception as e:
                print(f"Error selecting device automatically: {e}")
                return None

        if self.device_id and command[0] not in ["start-server", "kill-server"]:
            full_command.extend(["-s", self.device_id])

        full_command.extend(command)
        print(f"Executing: {' '.join(full_command)}")

        try:
            result = subprocess.run(full_command, capture_output=True, text=True, encoding="utf-8")
            return result
        except subprocess.CalledProcessError as e:
            print(f"Error executing command: {e}")
            return None

    def start_server(self):
        print("Starting ADB server...")
        result = self.run_adb_command(["start-server"])
        if result is not None:
            print(result.stdout)
            print(result.stderr)
        else:
            print("Failed to start ADB server.")

    def kill_server(self):
        print("Killing ADB server...")
        result = self.run_adb_command(["kill-server"])
        if result is not None:
            print(result.stdout)
            print(result.stderr)
        else:
            print("Failed to kill ADB server.")

    # ======================================================

    def root_device(self):
        print("Step 1: Rooting device...")
        commands = [
            ["wait-for-device", "shell", "setprop", "service.dev.mode", "1"],
            ["wait-for-device", "remount"],
        ]

        for cmd in commands:
            res = self.run_adb_command(cmd)
            print(res.stdout)
            print(res.stderr)

    def start_data_collection(self):
        print("Step 2: Starting data collection...")
        self.run_adb_command(["wait-for-device"])
        self.run_adb_command(["root"])
        self.run_adb_command(["shell", "dumpsys", "-t", "120", "android.yvr.trackingservice", "--dump_dataset", "6"])

    def stop_data_collection(self):
        print("Step 4: Stopping data collection...")
        self.run_adb_command(["wait-for-device"])
        self.run_adb_command(["root"])
        self.run_adb_command(["shell", "dumpsys", "-t", "120", "android.yvr.trackingservice", "--dump_dataset", "0"])

    def wait_for_collection(self, collect_time):
        print(f"Step 3: Collecting data for {collect_time} seconds...")
        time.sleep(collect_time)

    def pull_datasets(self):
        print("Step 5: Pulling datasets...")

        datasets = [
            "ServiceDataLoggerRecord",
        ]

        for dataset_name in datasets:
            self._pull_single_dataset(dataset_name)

    def _pull_single_dataset(self, dataset_name):
        print(f"Pulling {dataset_name}...")

        src_folder = f"/sdcard/{dataset_name}"
        # self._rm_pc_folder(dataset_name)
        self._pull_folder(src_folder)
        self._rm_mobile_folder(src_folder)

    def _rm_mobile_folder(self, folder):
        print(f"Delete {folder} from mobile")
        self.run_adb_command(["wait-for-device"])
        self.run_adb_command(["shell", "rm", "-rf", folder])

    def _rm_pc_folder(self, folder):
        print(f"Delete local {folder}")
        if os.path.exists(folder):
            import shutil
            shutil.rmtree(folder)

    def _pull_folder(self, folder):
        print(f"Pull {folder}")
        self.run_adb_command(["wait-for-device"])

        local_path=os.path.abspath("files/eye/data")
        self.run_adb_command(["pull", folder, local_path ])


    def collect_data(self, collect_time):
        print(f"Starting data collection for {collect_time} seconds...")

        try:
            self.start_server()
            self.root_device()
            self.start_data_collection()
            self.wait_for_collection(collect_time)
            self.stop_data_collection()
            self.pull_datasets()

            print("Data collection completed!")
            return True

        except Exception as e:
            print(f"Error during data collection: {e}")
            return False

    def test_delay(self):

        self.root_device()
        print(f"Testing delay...")
        self.run_adb_command(["wait-for-device"])
        test_path = os.path.abspath("files/eye/libs/delay")
        algo_path = os.path.abspath("files/eye/libs/libAlgo.so")

        self.run_adb_command(["push", test_path, r"/data/local/tmp/delay"])
        self.run_adb_command(["push", algo_path, r"/data/local/tmp/libAlgo.so"])
        self.run_adb_command(["shell", "chmod", "+x", "/data/local/tmp/delay"])

        try:
            # 运行demo并捕获输出
            result = self.run_adb_command(["shell", "LD_LIBRARY_PATH=/data/local/tmp", "/data/local/tmp/delay"])
            if not result:
                print("Demo执行无输出")
                return 0.0
            result = result.stdout.strip()
            # 从输出中提取所有时间值（微秒）
            # 支持多种可能的格式变体
            time_patterns = [
                r'Processing time:\s*(\d+(\.\d+)?)\s*ms',
            ]

            matches = []
            for pattern in time_patterns:
                matches.extend(re.findall(pattern, result, re.IGNORECASE))
            if matches:
                times = [float(match[0]) for match in matches]
                avg_time = sum(times) / len(times)
                print(f"Average Processing Time: {avg_time} ms")
                return avg_time
            else:
                print("未找到时间信息")
                return 0.0

        except Exception as e:
            print(f"测试延迟时发生错误: {e}")
            return 0.0
    def test_rate(self):

        self.root_device()
        print(f"Testing rate...")
        self.run_adb_command(["wait-for-device"])
        test_path = os.path.abspath("files/eye/libs/rate")
        algo_path = os.path.abspath("files/eye/libs/libAlgo.so")

        self.run_adb_command(["push", test_path, r"/data/local/tmp/rate"])
        self.run_adb_command(["push", algo_path, r"/data/local/tmp/libAlgo.so"])
        self.run_adb_command(["shell", "chmod", "+x", "/data/local/tmp/rate"])

        try:
            # 运行demo并捕获输出
            result = self.run_adb_command(["shell", "LD_LIBRARY_PATH=/data/local/tmp", "/data/local/tmp/rate"])
            print(result)
            if not result:
                print("Demo执行无输出")
                return 0.0
            result = result.stdout.strip()
            # 从输出中提取所有时间值（微秒）
            # 支持多种可能的格式变体
            time_pattern = r'Processing time:\s*(\d+(\.\d+)?)\s*ms'   
            frame_pattern = r"Processing number:\s*(\d+)"
            time_match = re.findall(time_pattern, result, re.IGNORECASE)
            frame_match = re.findall(frame_pattern, result, re.IGNORECASE)
            print(time_match,frame_match)
            if time_match and frame_match:
                total_time = float(time_match[0][0])
                total_frames = int(frame_match[0])
                rate = total_frames / (total_time / 1000.0)  # 转换为秒
                print(f"Processing Rate: {rate} frames/sec")
                return total_time, total_frames,rate
            else:
                print("未找到时间信息")
                return 0.0, 0.0,0.0

        except Exception as e:
            print(f"测试延迟时发生错误: {e}")
            return 0.0



